import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.border.CompoundBorder;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import javax.swing.JButton;

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * ==================================================================
 * GENERAL NOTES
 * ==================================================================
 * - The bounds of each component in the Workspace is calculated based
 * on  the bounds of the Workspace. e.g. the height of a component is 
 * always set to be 20% of the height of the workspace. Likewise, the 
 * x position of a component is always set to be half of the width of
 * Workspace minus 20 (width of component = (getWidth / 2) - 20). This
 * way, the layout and proportions of the components in Workspace will
 * always be the same no matter what the bounds of the Workspace are.
 * ===================================================================
 *
 */

public class Workspace extends JPanel {

	private Test test;
	private Session session;
	private int index;
	private int sessionIndex;
	private ImageGallery imageGallery;
	private Navigation navigation;
	private JButton selectedButton;
	private IconResizer resizer;
	/**
	 * Create the panel.
	 */
	public Workspace(int x, int y, int width, int height, Navigation nav) {
		test = new Test();
		resizer = new IconResizer (null);
		test.addSession(new Session(false));
		session = test.getSession(0);
		navigation = nav;
		index = 0;
		sessionIndex = 0;
		setBorder(new CompoundBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null), null));
		setBounds(x, y, width, height); // set bounds of Workspace
		setBackground(Color.WHITE);
		setLayout(null);
	}
	
	public void createNewProblem (){
		session.addProblem(true);
		index = session.getNoOfProblems() - 1;
		session.getProblem(index).addComparison("", true);
		session.getProblem(index).addComparison("", false);
		final JButton btnNewButton = new JButton("Sample");
		btnNewButton.setBorder(new LineBorder(Color.BLACK, 3));
		btnNewButton.setName("00");
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
			}
		});
		btnNewButton.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				if (btnNewButton.getName().length() > 2){
					ImageIcon image = new ImageIcon(btnNewButton.getName().substring(2));
					resizer.setImage(image);
					resizer.resize(btnNewButton.getHeight(), btnNewButton.getWidth());
					btnNewButton.setIcon(resizer.getImage());
				}
			}
		});
		btnNewButton.setBackground(Color.WHITE);
		int yDivision = getHeight() / 2; // half of height of Workspace
		int height = (int)(((float)yDivision / 100) * 80); // calculate height of sample and comparisons slots
		int sampleWidth = getWidth() / 3; // calculate width of sample slot
		btnNewButton.setBounds((getWidth() / 2) - (sampleWidth / 2), yDivision / 10, sampleWidth, height); // set bounds for sample slot
		add(btnNewButton);

		int xDivision = getWidth() / session.getProblem(index).getNoOfComparisons();
		for (int i = 0; i < session.getProblem(index).getNoOfComparisons(); i++ ){
			if (session.getProblem(index).getComparison(i).getAnswer()){	
				int x = (xDivision * i) + (xDivision / 10); // calculate X position of comparison slot
				int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
				final JButton button = new JButton("Correct Comparison");
				button.setBorder(new LineBorder (Color.GREEN, 3));
				button.setName("1" + (i + 1));
				button.addMouseListener(new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
					}
				});
				button.addComponentListener(new ComponentAdapter() {
					@Override
					public void componentResized(ComponentEvent arg0) {
						if (button.getName().length() > 2){
							ImageIcon image = new ImageIcon(button.getName().substring(2));
							resizer.setImage(image);
							resizer.resize(button.getHeight(), button.getWidth());
							button.setIcon(resizer.getImage());
						}
					}
				});
				button.setBackground(Color.WHITE);
				button.setBounds(x, yDivision + (yDivision / 10), width, height); // set bounds of comparison slot
				add(button);
				button.updateUI();
			} else {
				int x = (xDivision * i) + (xDivision / 10); // calculate X position of comparison slot
				int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
				final JButton button = new JButton("Incorrect Comparison");
				button.setBorder(new LineBorder (Color.RED, 3));
				button.setName("2" + (i + 1));
				button.addMouseListener(new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
					}
				});
				button.addComponentListener(new ComponentAdapter() {
					@Override
					public void componentResized(ComponentEvent arg0) {
						if (button.getName().length() > 2){
							ImageIcon image = new ImageIcon(button.getName().substring(2));
							resizer.setImage(image);
							resizer.resize(button.getHeight(), button.getWidth());
							button.setIcon(resizer.getImage());
						}
					}
				});
				button.setBackground(Color.WHITE);
				button.setBounds(x, yDivision + (yDivision / 10), width, height); // set bounds of comparison slot
				add(button);
				button.updateUI();
			}
		}
		navigation.addDisplay(session.getProblem(index));
		this.repaint();
	}
	
	public int getIndex (){
		return index;
	}
	
	public void loadProblem (int problemIndex){
		index = problemIndex;
		final JButton btnNewButton = new JButton("Sample");
		btnNewButton.setBorder(new LineBorder (Color.BLACK, 3));
		btnNewButton.setName("00" + session.getProblem(index).getSample());
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
			}
		});
		btnNewButton.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				if (btnNewButton.getName().length() > 2){
					ImageIcon image = new ImageIcon(btnNewButton.getName().substring(2));
					resizer.setImage(image);
					resizer.resize(btnNewButton.getHeight(), btnNewButton.getWidth());
					btnNewButton.setIcon(resizer.getImage());
				}
			}
		});
		btnNewButton.setBackground(Color.WHITE);
		int yDivision = getHeight() / 2;
		int height = (int)(((float)yDivision / 100) * 80); // calculate height of sample slot
		int sampleWidth = getWidth() / 3; // calculate width of sample slot
		btnNewButton.setBounds((getWidth() / 2) - (sampleWidth / 2), yDivision / 10, sampleWidth, height); // set bounds of sample slot
		resizer.setImage(new ImageIcon (session.getProblem(index).getSample()));
		resizer.resize(btnNewButton.getHeight(), btnNewButton.getWidth());
		btnNewButton.setIcon(resizer.getImage());
		add(btnNewButton);

		int xDivision = getWidth() / session.getProblem(index).getNoOfComparisons();
		for (int i = 0; i < session.getProblem(index).getNoOfComparisons(); i++ ){
			if (session.getProblem(index).getComparison(i).getAnswer()){	
				int x = (xDivision * i) + (xDivision / 10); // calculate X position of comparison slot
				int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
				final JButton button = new JButton("Correct Comparison");
				button.setBorder(new LineBorder (Color.GREEN, 3));
				button.setName("1" +  + (i + 1) + session.getProblem(index).getComparison(i).getImage());
				button.addMouseListener(new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
					}
				});
				button.addComponentListener(new ComponentAdapter() {
					@Override
					public void componentResized(ComponentEvent arg0) {
						if (button.getName().length() > 2){
							ImageIcon image = new ImageIcon(button.getName().substring(2));
							resizer.setImage(image);
							resizer.resize(button.getHeight(), button.getWidth());
							button.setIcon(resizer.getImage());
						}
					}
				});
				button.setBackground(Color.WHITE);
				button.setBounds(x, yDivision + (yDivision / 10), width, height); // set bounds of comparison slot
				resizer.setImage(new ImageIcon(session.getProblem(index).getComparison(i).getImage()));
				resizer.resize(button.getHeight(), button.getWidth());
				button.setIcon(resizer.getImage());
				add(button);
				button.updateUI();
			} else {
				int x = (xDivision * i) + (xDivision / 10); // calculate X position of comparison slot
				int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
				final JButton button = new JButton("Incorrect Comparison");
				button.setBorder(new LineBorder (Color.RED, 3));
				button.setName("2" + (i + 1) + session.getProblem(index).getComparison(i).getImage());
				
				button.addMouseListener(new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
					}
				});
				button.addComponentListener(new ComponentAdapter() {
					@Override
					public void componentResized(ComponentEvent arg0) {
						if (button.getName().length() > 2){
							ImageIcon image = new ImageIcon(button.getName().substring(2));
							resizer.setImage(image);
							resizer.resize(button.getHeight(), button.getWidth());
							button.setIcon(resizer.getImage());
						}
					}
				});
				button.setBackground(Color.WHITE);
				button.setBounds(x, yDivision + (yDivision / 10), width, height); // set bounds of comparison slot
				resizer.setImage(new ImageIcon(session.getProblem(index).getComparison(i).getImage()));
				resizer.resize(button.getHeight(), button.getWidth());
				button.setIcon(resizer.getImage());
				add(button);
				button.updateUI();
			}
		}
		this.updateUI();
	}
	
	public void addComparison (){
		session.getProblem(index).addComparison(null, false);
		final JButton button = new JButton("Incorrect Comparison");
		button.setBorder(new LineBorder (Color.RED, 3));
		button.setName("2" + (session.getProblem(index).getNoOfComparisons()));
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				selectedButton = (JButton) Workspace.this.getComponentAt(getMousePosition());
			}
		});
		button.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				if (button.getName().length() > 2){
					ImageIcon image = new ImageIcon(button.getName().substring(2));
					resizer.setImage(image);
					resizer.resize(button.getHeight(), button.getWidth());
					button.setIcon(resizer.getImage());
				}
			}
		});
		button.setBackground(Color.WHITE);
		add(button);
		resizeProblem();
		navigation.addDisplaySlot();
	}
	
	public void removeSelectedComparison (){
		char c = selectedButton.getName().charAt(1);
		int componentIndex = c - 48;
		session.getProblem(index).removeComparison(componentIndex - 1);
		remove(componentIndex);
		int xDivision = getWidth() / session.getProblem(index).getNoOfComparisons();
		for (int i = 0; i < session.getProblem(index).getNoOfComparisons(); i++ ){
			int x = (xDivision * i) + (xDivision / 10); // calculate X position of comparison slot
			int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
			JButton comparison = (JButton) getComponent(i + 1);
			comparison.setBounds(x, comparison.getY(), width, comparison.getHeight()); // set bounds of comparison slot
			String compName = comparison.getName();
			if (compName.length() > 2){
			    comparison.setName(compName.charAt(0) + (i + 1) + compName.substring(2));
			} else {
				comparison.setName(compName.charAt(0) + (i + 1) + "");
			}
		}
		navigation.removeDisplaySlot(componentIndex);
		updateUI();
	}
	
	public void removeProblem (int problemIndex){
		session.removeProblem(problemIndex);
		navigation.removeDisplay(problemIndex);
	}
	
	public void updateProblem (){
		int comparisonIndex = 0;
		for (int i = 0; i < this.getComponentCount(); i++){
			if (this.getComponent(i).getClass().getName().equals("javax.swing.JButton")){
				JButton button = (JButton)this.getComponent(i);
				if (button.getName().charAt(0) == '0'){
					session.getProblem(index).setSample(button.getName().substring(2));
				} else if (button.getName().charAt(0) == '1'){
					session.getProblem(index).getComparison(comparisonIndex).setImage(button.getName().substring(2));
					session.getProblem(index).getComparison(comparisonIndex).setAnswer(true);
					comparisonIndex++;
				} else if (button.getName().charAt(0) == '2'){
					session.getProblem(index).getComparison(comparisonIndex).setImage(button.getName().substring(2));
					session.getProblem(index).getComparison(comparisonIndex).setAnswer(false);
					comparisonIndex++;
				}
			}
		}
	}
	
	public void clearWorkspace (){
		this.removeAll();
	}
	
	public void setButtonImage (String imageName){
		resizer.setImage(new ImageIcon(imageName));
		resizer.resize(selectedButton.getHeight(), selectedButton.getWidth());
		selectedButton.setIcon(resizer.getImage());
		selectedButton.setName(selectedButton.getName().substring(0, 2) + imageName);
		navigation.updateDisplay(selectedButton.getName().substring(1));
		selectedButton.updateUI();
	}
	
	public void setImageGallery (ImageGallery imgGallery){
		imageGallery = imgGallery;
	}
	
	public void setNavigation (Navigation nav){
		navigation = nav;
	}
	
	public Problem getCurrentProblem (){
		return session.getProblem(index);
	}
	
	public Session getSession (){
		return session;
	}
	
	public Test getTest (){
		return test;
	}
	
	public int getSelectedButtonType (){
		if (selectedButton != null){
			char c = selectedButton.getName().charAt(0);
			return (c - 48);
		}
		return -1;
	}
	
	public void addSession (){
		test.addSession(new Session(false));
		loadSession(test.getNoOfSessions() - 1);
		sessionIndex = test.getNoOfSessions() - 1;
		navigation.clearDisplayContainer();
		createNewProblem();
	}
	
	public void loadSession (int i){
		session = test.getSession(i);
		sessionIndex = i;
	}
	
	public int getNoOfSessions (){
		return test.getNoOfSessions();
	}
	
	public void removeSession(){
		test.removeSession(sessionIndex);
		if (sessionIndex >= test.getNoOfSessions()){
		   sessionIndex = test.getNoOfSessions() - 1;
		}
	}
	
	public int getSessionIndex (){
		return sessionIndex;
	}
	
	// resize problem
	public void resizeProblem (){
		int yDivision = getHeight() / 2; // half of height of Workspace
		int height = (int)(((float)yDivision / 100) * 80); // calculate height of slots
		int sampleWidth = getWidth() / 3; // calculate width of sample slot
		getComponent(0).setBounds((getWidth() / 2) - (sampleWidth / 2), yDivision / 10, sampleWidth, height);
		int xDivision = getWidth() / session.getProblem(index).getNoOfComparisons();
		for (int i = 1; i < getComponentCount(); i++ ){	
				int x = (xDivision * (i - 1)) + (xDivision / 10); // calculate x position of comparison slot
				int width = (int)(((float)xDivision / 100) * 80); // calculate width of comparison slot
				getComponent(i).setBounds(x, yDivision + (yDivision / 10), width, height); // set bounds of comparison
		}
		updateUI();
	}
	
	public void loadTest (Test t){
		test = t;
		session = test.getSession(0);
		index = 0;
		for (int i = 0; i <session.getNoOfProblems(); i++){
			navigation.addDisplay(session.getProblem(i));
		}
		navigation.updateSessionList(test);
		loadProblem(0);
	}
}
